﻿namespace WebDevUtilities.VsixPkg
{
    using Microsoft.VisualStudio.Shell;
    using Microsoft.VisualStudio.Shell.Interop;
    using System;
    using System.ComponentModel.Design;
    using System.Diagnostics;
    using System.Globalization;
    using System.Runtime.InteropServices;
    using CssSpriteGenerator = Extensions.CssSpriteGenerator;
    using AspTemplateConverter = Extensions.AspTemplateConverter;
    using EnvDTE;
    using EnvDTE80;
    using WebDevUtilities.VsixPkg.Properties;

    [PackageRegistration(UseManagedResourcesOnly = true)]
    // This attribute is used to register the information needed to show this package
    // in the Help/About dialog of Visual Studio.
    [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
    // This attribute is needed to let the shell know that this package exposes some menus.
    [ProvideMenuResource("Menus.ctmenu", 1)]
    // This attribute registers a tool window exposed by this package.
    [ProvideToolWindow(typeof(CssSpriteGenerator.CssSpriteGeneratorToolWindowPane))]
    [ProvideToolWindow(typeof(AspTemplateConverter.AspTemplateConverterToolWindowPane))]
    [Guid(GuidList.guidWebDevUtilitiesPkg)]
    public sealed class WebDevloperUtilitiesPackage : Package
    {
        private MenuCommand cmdCssSpriteGenerator;

        public MenuCommand CmdCssSpriteGenerator
        {
            get { return cmdCssSpriteGenerator; }
            set { cmdCssSpriteGenerator = value; }
        }

        public WebDevloperUtilitiesPackage()
        {
            Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
        }

        private OutputWindowPane wduOutputWindowPane;

        public OutputWindowPane WduOutputWindowPane
        { 
            get
            {
                if (wduOutputWindowPane == null)
                {
                    wduOutputWindowPane = InitializeWduOutputWindowPane(); 
                }
                return wduOutputWindowPane; 
            }
        }

        private OutputWindowPane InitializeWduOutputWindowPane()
        {
            EnvDTE.Window win = (GetGlobalService(typeof(DTE)) as DTE2).Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
            OutputWindow outputWindow = (OutputWindow)win.Object;
            OutputWindowPane outputWindowPane = outputWindow.OutputWindowPanes.Add(Resources.OutputWindowPaneTitle);
            OutputWindowPane a = outputWindow.OutputWindowPanes.Item(Resources.OutputWindowPaneTitle);

            return outputWindowPane;
        }

        #region Package Members
        protected override void Initialize()
        {
            Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
            base.Initialize();
            OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
            if (null != mcs)
            {
                CommandID menuCmdID = new CommandID(GuidList.guidWebDevUtilitiesCmdSet, (int)PkgCmdIDList.cmdidCssSpriteGeneratorToolsMenu);
                MenuCommand menuCmd = new MenuCommand(ShowCssSpriteGeneratorToolWindow, menuCmdID);
                mcs.AddCommand(menuCmd);
                menuCmdID = new CommandID(GuidList.guidWebDevUtilitiesCmdSet, (int)PkgCmdIDList.cmdidCssSpriteGeneratorSolutionExplorerMenu);
                menuCmd = new MenuCommand(ShowCssSpriteGeneratorToolWindow, menuCmdID);
                mcs.AddCommand(menuCmd);
                menuCmdID = new CommandID(GuidList.guidWebDevUtilitiesCmdSet, (int)PkgCmdIDList.cmdidCssSpriteGeneratorQuickSolutionExplorerMenu);
                menuCmd = new MenuCommand(CssSpriteGeneratorQuickCmd, menuCmdID);
                mcs.AddCommand(menuCmd);
                //OleMenuCommand oleMenuCmd = new OleMenuCommand(CssSpriteGeneratorCmdVisibility, menuCmdID);
                //mcs.AddCommand(oleMenuCmd);
                menuCmdID = new CommandID(GuidList.guidWebDevUtilitiesCmdSet, (int)PkgCmdIDList.cmdidCssSpriteGeneratorViewMenu);
                menuCmd = new MenuCommand(ShowCssSpriteGeneratorToolWindow, menuCmdID);
                mcs.AddCommand(menuCmd);
                menuCmdID = new CommandID(GuidList.guidWebDevUtilitiesCmdSet, (int)PkgCmdIDList.cmdidAspTemplateConverterToolsMenu);
                menuCmd = new MenuCommand(ShowAspTemplateConverterToolWindow, menuCmdID);
                mcs.AddCommand(menuCmd);
                menuCmdID = new CommandID(GuidList.guidWebDevUtilitiesCmdSet, (int)PkgCmdIDList.cmdidAspTemplateConverterSolutionExplorerMenu);
                menuCmd = new MenuCommand(ShowAspTemplateConverterToolWindow, menuCmdID);
                mcs.AddCommand(menuCmd);
                menuCmdID = new CommandID(GuidList.guidWebDevUtilitiesCmdSet, (int)PkgCmdIDList.cmdidAspTemplateConverterQuickSolutionExplorerMenu);
                menuCmd = new MenuCommand(AspTemplateConverterQuickCmd, menuCmdID);
                mcs.AddCommand(menuCmd);
                //oleMenuCmd = new OleMenuCommand(AspTemplateConverterCmdVisibility, menuCmdID);
                //mcs.AddCommand(oleMenuCmd);
                menuCmdID = new CommandID(GuidList.guidWebDevUtilitiesCmdSet, (int)PkgCmdIDList.cmdidAspTemplateConverterViewMenu);
                menuCmd = new MenuCommand(ShowAspTemplateConverterToolWindow, menuCmdID);
                mcs.AddCommand(menuCmd);
                menuCmdID = new CommandID(GuidList.guidWebDevUtilitiesCmdSet, (int)PkgCmdIDList.cmdidCodeWasherSolutionExplorerMenu);
                menuCmd = new MenuCommand(RunCodeWasher, menuCmdID);
                mcs.AddCommand(menuCmd);
            }
        }
        #endregion

        #region Package Commands
        private void ShowCssSpriteGeneratorToolWindow(object sender, EventArgs e)
        {
            ToolWindowPane window = this.FindToolWindow(typeof(CssSpriteGenerator.CssSpriteGeneratorToolWindowPane), 0, true);
            if ((null == window) || (null == window.Frame))
            {
                throw new NotSupportedException(Properties.Resources.CanNotCreateWindow);
            }
            IVsWindowFrame windowFrame = (IVsWindowFrame)window.Frame;
            Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show());
        }

        private void CssSpriteGeneratorQuickCmd(object sender, EventArgs e)
        {
            ToolWindowPane window = this.FindToolWindow(typeof(CssSpriteGenerator.CssSpriteGeneratorToolWindowPane), 0, true);
            if ((null == window) || (null == window.Frame))
            {
                throw new NotSupportedException(Properties.Resources.CanNotCreateWindow);
            }
            IVsWindowFrame windowFrame = (IVsWindowFrame)window.Frame;
            Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show());
        }

        private void ShowAspTemplateConverterToolWindow(object sender, EventArgs e)
        {
            ToolWindowPane window = this.FindToolWindow(typeof(AspTemplateConverter.AspTemplateConverterToolWindowPane), 0, true);
            if ((null == window) || (null == window.Frame))
            {
                throw new NotSupportedException(Properties.Resources.CanNotCreateWindow);
            }
            IVsWindowFrame windowFrame = (IVsWindowFrame)window.Frame;
            Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show());
        }

        private void AspTemplateConverterQuickCmd(object sender, EventArgs e)
        {
            ToolWindowPane window = this.FindToolWindow(typeof(AspTemplateConverter.AspTemplateConverterToolWindowPane), 0, true);
            if ((null == window) || (null == window.Frame))
            {
                throw new NotSupportedException(Properties.Resources.CanNotCreateWindow);
            }
            IVsWindowFrame windowFrame = (IVsWindowFrame)window.Frame;
            Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show());
        }

        private void RunCodeWasher(object sender, EventArgs e)
        {
            TestCall(sender, e);
        }

        private void TestCall(object sender, EventArgs e)
        {
            IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));
            Guid clsid = Guid.Empty;
            int result;
            Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox(
                       0,
                       ref clsid,
                       "Test",
                       string.Format(CultureInfo.CurrentCulture, "Inside {0}.MenuItemCallback()", this.ToString()),
                       string.Empty,
                       0,
                       OLEMSGBUTTON.OLEMSGBUTTON_OK,
                       OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                       OLEMSGICON.OLEMSGICON_INFO,
                       0,        // false
                       out result));
        }
        #endregion

        private void CssSpriteGeneratorCmdVisibility(object sender, EventArgs e)
        {
            OleMenuCommand menuCommand = sender as OleMenuCommand;
            if (menuCommand != null)
            {
                IntPtr hierarchyPtr, selectionContainerPtr;
                uint projectItemId;
                IVsMultiItemSelect mis;
                IVsMonitorSelection monitorSelection = (IVsMonitorSelection)Package.GetGlobalService(typeof(SVsShellMonitorSelection));
                monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr);

                IVsHierarchy hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy;
                if (hierarchy != null)
                {
                    object value;
                    hierarchy.GetProperty(projectItemId, (int)__VSHPROPID.VSHPROPID_Name, out value);
                    string file = value.ToString();
                    if (value != null &&
                        file.EndsWith(CssSpriteGenerator.FileType.BMP) ||
                        file.EndsWith(CssSpriteGenerator.FileType.GIF) ||
                        file.EndsWith(CssSpriteGenerator.FileType.JPEG) ||
                        file.EndsWith(CssSpriteGenerator.FileType.JPG) ||
                        file.EndsWith(CssSpriteGenerator.FileType.PNG))
                    {
                        menuCommand.Visible = true;
                    }
                    else
                    {
                        menuCommand.Visible = false;
                    }
                }
            }
        }

        private void AspTemplateConverterCmdVisibility(object sender, EventArgs e)
        {
            OleMenuCommand menuCommand = sender as OleMenuCommand;
            if (menuCommand != null)
            {
                IntPtr hierarchyPtr, selectionContainerPtr;
                uint projectItemId;
                IVsMultiItemSelect mis;
                IVsMonitorSelection monitorSelection = (IVsMonitorSelection)Package.GetGlobalService(typeof(SVsShellMonitorSelection));
                monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr);

                IVsHierarchy hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy;
                if (hierarchy != null)
                {
                    object value;
                    hierarchy.GetProperty(projectItemId, (int)__VSHPROPID.VSHPROPID_Name, out value);
                    string file = value.ToString();
                    if (value != null &&
                        file.EndsWith(AspTemplateConverter.FileType.ASPX) ||
                        file.EndsWith(AspTemplateConverter.FileType.ASCX))
                    {
                        menuCommand.Visible = true;
                    }
                    else
                    {
                        menuCommand.Visible = false;
                    }
                }
            }
        }
    }
}
